//@author A0097978X
package flexiCommands;

import java.lang.StringBuilder;
import java.lang.Integer;

public class ParsePendingInfo extends ParseInfo{

	private static final String ERROR_MESSAGE_TOO_FEW_ARGUMENT = "Too little info";
	private static final String ERROR_MESSAGE_UNACCEPTABLE_ARGUMENT = "Please enter an integer only";
	private static final String ERROR_MESSAGE_OPTION_0 = "Please re-enter your option";

	private static final int QUERY_TYPE = 2;
	private static final int OPTION_TYPE = 1;
	private static final int COMMAND = 0;
	private static final int UNPROCESSED = 0;
	private static final int TWO_ARGUMENTS = 2;
	
	private static final String ONE_SPACE = " ";
	private static final String ALL_AND_COMPLETE = "(ALL|COMPLETE)";

	private String[] infoToParse;
	private Command processedCmd;
	private int[] typeDeterminer;

	public ParsePendingInfo(String[] userInfo) throws Exception{
		super(userInfo);

		if(userInfo.length < TWO_ARGUMENTS)
			throw new Exception(ERROR_MESSAGE_TOO_FEW_ARGUMENT);
	}

	@Override
	public Command execute() throws Exception{
		infoToParse = super.infoString;
		processedCmd = super.cmdObj;

		processedCmd.setCommandType(infoToParse[COMMAND]);

		typeDeterminer = new int[infoToParse.length];

//====================== Flexible Arguments Type =======================//

		//boolean optionChosen = false;
		for(int i=1; i<infoToParse.length; i++) {
			if(typeDeterminer[i] == 0)	{

				if(isAlpha(infoToParse[i])) {
					if(infoToParse[i].toUpperCase().matches(ALL_AND_COMPLETE))
						typeDeterminer[i] = QUERY_TYPE;
					else
						throw new Exception(ERROR_MESSAGE_UNACCEPTABLE_ARGUMENT); }
				else {
					typeDeterminer[i] = OPTION_TYPE; 
					break;
				}
			}
		}

//=================== Parse & Generate Respective Type ===================//
		if(checkTypeDeterminer()) {
			for(int q=1; q<typeDeterminer.length; q++) {
				if(typeDeterminer[q] == QUERY_TYPE) {
					generateQuery();
					break;
				}
			}
			
			for(int q=1; q<typeDeterminer.length; q++) {
				if(typeDeterminer[q] == OPTION_TYPE) {
					generateOption();
					break;
				}
			}	
		}

		return processedCmd;
	}

	private boolean checkTypeDeterminer() {
		for(int i=1; i<typeDeterminer.length; i++) {
			if(typeDeterminer[i] == UNPROCESSED)
				return false;
		}

		return true;
	}

	private void generateOption() throws Exception{
		StringBuilder option = new StringBuilder();
		for(int i=1; i<typeDeterminer.length; i++) {
			if(typeDeterminer[i] == OPTION_TYPE) {
				if(Integer.parseInt(infoToParse[i])==0) throw new Exception(ERROR_MESSAGE_OPTION_0);
				else option.append(infoToParse[i]);
				break;
			}
		}
		processedCmd.setOption(Integer.parseInt(option.toString()));
	}
	
	private void generateQuery() {
		StringBuilder query = new StringBuilder();
		for(int i=1; i<typeDeterminer.length; i++) {
			if(typeDeterminer[i] == QUERY_TYPE) {
				query.append(infoToParse[i] + ONE_SPACE);
			}
		}

		processedCmd.setQuery(query.toString().trim());
	}

	private boolean isAlpha(String str) {
    	char[] chars = str.toCharArray();

    	for (char c : chars) {
        	if(!Character.isLetter(c)) 
          	  	return false;
    	}

    	return true;
	}


}